package com.netease.commenta.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Ben on 2017/2/26.
 */

public class FlowLayout extends ViewGroup {
    private int maxLines = 0;
    private int nowTop;
    private List<View> viewsInLine = new ArrayList<View>();

    public FlowLayout(Context context) {
        super(context);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        final int[] mAttr = {android.R.attr.text};
        TypedArray ta = context.obtainStyledAttributes(attrs, mAttr);
        maxLines = ta.getInteger(0, 0);
        ta.recycle();
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int lines = 0;
        int lineWidth = 0, lineHeight = 0;
        int measuredWidth = 0, measuredHeight = 0;

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() == View.GONE) {
                continue;
            }
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
            MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
            int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
            int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;

            if (widthMode != MeasureSpec.UNSPECIFIED && lineWidth + childWidth > width) {
                measuredHeight += lineHeight;
                if (measuredWidth < lineWidth) {
                    measuredWidth = lineWidth;
                }
                lineWidth = 0;
                lineHeight = 0;
                if (maxLines > 0 && maxLines >= lines) {
                    break;
                } else {
                    lines++;
                }
            }
            lineWidth += childWidth;
            if (lineHeight < childHeight) {
                lineHeight = childHeight;
            }
        }
        measuredHeight += lineHeight;
        if (measuredWidth < lineWidth) {
            measuredWidth = lineWidth;
        }

        setMeasuredDimension(
                (widthMode == MeasureSpec.EXACTLY) ? width : measuredWidth,
                (heightMode == MeasureSpec.EXACTLY) ? height : measuredHeight
        );
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        int width = getWidth();
        int lines = 0;
        int lineWidth = 0, lineHeight = 0;
        viewsInLine.clear();
        nowTop = 0;

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() == View.GONE) {
                continue;
            }
            MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
            int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
            int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;

            if (lineWidth + childWidth > width) {
                layoutLine(lineHeight);
                lineWidth = 0;
                lineHeight = 0;
                if (maxLines > 0 && maxLines >= lines) {
                    break;
                } else {
                    lines++;
                }
            }
            viewsInLine.add(child);
            lineWidth += childWidth;

            if (lineHeight < childHeight) {
                lineHeight = childHeight;
            }
        }
        layoutLine(lineHeight);
    }


    private void layoutLine(int lineHeight) {
        int count = viewsInLine.size();
        int nowLeft = 0;
        for (int i = 0; i < count; i++) {
            View child = viewsInLine.get(i);

            MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
            int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
            int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
            child.layout(nowLeft + lp.leftMargin, nowTop + lp.rightMargin,
                    nowLeft + childWidth - lp.rightMargin, nowTop + childHeight - lp.bottomMargin);
            nowLeft += childWidth;
        }
        viewsInLine.clear();
        nowTop += lineHeight;
    }
}
